(function (window) {
    // 将状态声明为常量。全局（应用）性质的常量一般要求大写。
    const PENDING = "pending";
    const FULFILLED = "fulfilled";
    const REJECTED = "rejected"
    // 1- 将构造函数体内的语句放置到constructor构造器函数中
    // 2- 将原型对象当中的方法直接放置到class中,方法之间不要使用逗号.
    // 3- 设置静态方法resolve,reject,all,race
    class Promise {
        static resolve(value) {
            // 判断value是否为Promise,
            // 如果是Promise直接返回,如果不是返回一个状态为成功,值为value的新的promise,
            if (value instanceof Promise) return value;
            else return new Promise(resolve => resolve(value));
        }
        static reject(value) {
            // 不管接收的值是什么,返回的永远是失败的promise,失败值为value
            // return new Promise(()=>{
            //     throw value;
            // })
    
            return new Promise((resovle, reject) => {
                reject(value);
            })
        }
        static all (promiseArr) {
            const arr = new Array(promiseArr.length);// 成功值,类型是一个数组
            let num = 0;
            return new Promise((resolve, reject) => {
                promiseArr.forEach((item, index) => {
                    item.then(value => {
                        num++;
                        arr[index] = value;
                        if (num === promiseArr.length) {
                            resolve(arr);
                        }
                    }, reason => {
                        reject(reason);// 将返回的promise设置为失败
                    })
                })
            })
    
        }
        static race(promiseArr) {
            return new Promise((resolve, reject) => {
                promiseArr.forEach(item => {
                    // item.then(value=>{
                    //     resolve(value);
                    // },reason=>{
                    //     reject(reason)
                    // })
    
                    item.then(resolve, reject);
                })
            })
    
        }
        constructor(executor) {
            // 增加实例属性state，初始值为pending
            this.state = PENDING;
            // 增加实例属性result,初始值为undefined
            this.result = undefined;
            // 增加属性,类型是一个数组,数组的元素类型写成对象,对象中拥有成功与失败的回调.
            this.callbackArr = [];
            const _resolve = value => {
                // 如果状态发生变化，那么后续代码不会执行
                if (this.state !== PENDING) return;
                // 将当前的状态更改为fulfilled,值为接收的value
                this.state = FULFILLED;
                this.result = value;


                // 遍历数组 callbackArr
                this.callbackArr.forEach(v => v.onResolved());
            }
            const _reject = value => {
                // 如果状态发生变化，那么后续代码不会执行
                if (this.state !== PENDING) return;
                // 将当前的状态更改为rejected,值为接收的value
                this.state = REJECTED;
                this.result = value;
                // 遍历数组 callbackArr
                this.callbackArr.forEach(v => v.onRejected());
            }
            try {
                executor(_resolve, _reject);
            } catch (err) {
                // 如果状态发生变化，那么后续代码不会执行
                _reject(err)
            }
        }
        then(onResolved, onRejected) {
            // 判断onResolved是否为一个函数,如果不是函数,可以设置默认值
            if (!(onResolved instanceof Function)) onResolved = value => value;
            // 判断onRejected是否为一个函数,如果不是函数,那么设置默认值
            if (!(onRejected instanceof Function)) {
                onRejected = reason => {
                    throw reason;
                }
            }
            // 返回一个新的promise,在执行器函数中直接判断状态调用对应的成功或失败回调
            // 根据成功或失败回调的返回结果，来修改返回promise的状态以及值。
            return new Promise((resolve, reject) => {
                function _common(callback) {
                    setTimeout(() => {
                        // 将成功回调的返回值赋值给常量value
                        try {
                            const value = callback(this.result);// 调用成功回调，并将成功值传递过去
                            // 判断value是否为Promise实例
                            if (value instanceof Promise) value.then(resolve, reject)
                            else resolve(value);
                        } catch (err) {
                            // 有异常,，将返回的新的Promise的状态更改为失败，值为异常信息
                            reject(err);
                        }
                    })
                }
                // 判断状态是否为成功
                if (this.state === FULFILLED) {
                    _common.call(this, onResolved);
                } else if (this.state === REJECTED) {
                    _common.call(this, onRejected);
                } else if (this.state === PENDING) {
                    // 增加callbackObj属性,用于保存更改状态后要调用的回调函数.
                    // this.callbackObj = {
                    //     onResolved:_common.bind(this,onResolved),
                    //     onRejected:_common.bind(this,onRejected)
                    // }

                    this.callbackArr.push({
                        onResolved: _common.bind(this, onResolved),
                        onRejected: _common.bind(this, onRejected)
                    })
                }
            })
        }
        catch(onRejected) {
            return this.then(undefined, onRejected)
        }
    }
    window.Promise = Promise;
})(window);